<template>
    <WithWait :loading="loading">
        <div class="contentLayout">
            <!-- 搜索表单 -->
            <div class="formSearch">
                <SupperFrom :model="form" :fileds="searchFileds" :option="searchOption" :inline="true" @submit="find" />
            </div>
            <!-- 数据表格 -->
            <div class="contentView">
                <div class="actionList">
                    <el-button v-permission="'system:menu:add'" type="primary" @click="add(undefined)"><svg-icon
                            name="add"></svg-icon>新 增</el-button>
                    <el-button v-permission="'system:menu:edit'" type="success"
                        :disabled="!table.rows || table.rows.length !== 1"><svg-icon name="edit"></svg-icon>修 改</el-button>
                    <el-button v-permission="'system:menu:remove'" type="danger"
                        :disabled="!table.rows || table.rows.length !== 1" @click="isdelete(table.rows![0])"><svg-icon
                            name="delete"></svg-icon>删 除</el-button>
                </div>
                <SupperTable :data="table.data" :column="tableColumn" @selection-change="selectionRows">
                    <template #status="scope">
                        <el-switch @change="modify(scope.row)" v-if="scope.row.type !== 'button'"
                            v-model="scope.row.status"></el-switch>
                    </template>
                    <template #icon="scope">
                        <svg-icon :class="'icon'" :name="scope.row.icon || 'yonghu1'"></svg-icon>
                    </template>
                    <template #link="scope">
                        <el-switch v-if="scope.row.type !== 'button'" v-model="scope.row.link"></el-switch>
                    </template>
                    <template #cache="scope">
                        <el-switch v-if="scope.row.type !== 'button'" v-model="scope.row.cache"></el-switch>
                    </template>
                    <template v-slot="{ row }">
                        <el-button v-permission="'system:menu:add'" circle type="primary" size="small"
                            @click="add(row._id)"><svg-icon name="add"></svg-icon></el-button>
                        <el-button v-permission="'system:menu:edit'" circle type="success" size="small"
                            @click="edit(row)"><svg-icon name="edit"></svg-icon></el-button>
                        <el-button v-permission="'system:menu:remove'" circle type="danger" size="small"
                            @click="isdelete(row)"><svg-icon name="delete"></svg-icon></el-button>
                    </template>
                </SupperTable>
            </div>
        </div>
        <!-- 弹出框操作 -->
        <el-dialog draggable :destroy-on-close="true" v-model="dialog.visible" :title="dialog.title" width="550">
            <SupperFrom :model="dialog.form" :option="dialogOption" :fileds="directoryFileds" :rules="directoryRules"
                :inline="false" @submit="submit" @cancel="dialog.visible = false" :label-width="'120px'" />
        </el-dialog>
    </WithWait>
</template>
<script lang="ts">

export default {
    name: "菜单管理"
}
</script>
<script lang='ts' setup>
import { appendMenu, getMenuList, removeMenu, updateMenu } from '@/api/system/menu';
import { Menu } from '@/types/menu';
import { handleResponse } from '@/utils/responseCode';
import { nextTick, reactive, ref, toRaw } from 'vue';
import SupperFrom from "@/components/Form/index.vue"
import { Form } from "@/types/form"
import { Table } from "@/types/table"
import SupperTable from "@/components/Table/index.vue"
import { ElMessage, ElMessageBox, FormRules } from 'element-plus';
// 页面加载loading
let loading = ref<boolean>(true)
// ===========搜索表单 start===========
let form = ref<Menu.MenuSearchQuery>({
})
// 搜索表单项
const searchOption: Form.Options = {
    btnList: ["reset", "submit"]
}
const searchFileds: Form.Fileds[] = [
    {
        label: "菜单名称",
        type: "input",
        key: "name",
        placeholder: "请输入菜单名称"
    },
    {
        label: "状态",
        type: "select",
        key: "status",
        placeholder: "请选择菜单状态",
        option: [
            { label: "启用", value: true },
            { label: "禁用", value: false },
        ]
    },
    {
        label: "是否外链",
        type: "select",
        key: "link",
        placeholder: "请选择是否外链",
        option: [
            { label: "是", value: true },
            { label: "否", value: false },
        ]
    },
    {
        label: "菜单类型",
        type: "select",
        key: "type",
        placeholder: "请选择菜单类型",
        option: [
            { label: "目录", value: "directory" },
            { label: "菜单", value: "menu" },
            { label: "按钮", value: "button" }
        ]
    },
]
// ===========搜索表单 end=============
// 异步option数据
const config = reactive<{
    parentidOption: Menu.TreeMenuList | undefined
}>({
    parentidOption: undefined
})
// ===========增加、修改表单配置项 start===========

interface DialogProps {
    title: "新增" | "修改",
    visible: boolean,
    form: Menu.Directory | Menu.Menu
}
// 新增、修改操作
const dialog = reactive<DialogProps>({
    title: "新增",
    visible: false,
    form: {
        parentid: "",
        name: "",
        status: true,
        type: "directory"
    },
})
// 搜索表单项
const dialogOption: Form.Options = {
    btnList: ["cancel", "submit"]
}
// 目录表单
const directoryFileds = ref<Form.Fileds[]>([
    {
        label: "父级目录",
        type: "treeSelect",
        key: "parentid",
        option: config.parentidOption
    },
    {
        label: "菜单类型",
        type: "radio",
        key: "type",
        option: [
            { label: "目录", value: "directory" },
            { label: "菜单", value: "menu" },
            { label: "按钮", value: "button" }
        ]
    },
    {
        label: "目录名称",
        type: "input",
        key: "name",
        show: (val: Menu.TreeMenuList) => {
            return val.type === "directory"
        }
    },
    {
        label: "菜单名称",
        type: "input",
        key: "name",
        show: (val: Menu.TreeMenuList) => {
            return val.type === "menu"
        }
    },
    {
        label: "按钮名称",
        type: "input",
        key: "name",
        show: (val: Menu.TreeMenuList) => {
            return val.type === "button"
        }
    },
    {
        label: "图标",
        type: "icon",
        key: "icon",
        show: (val: Menu.TreeMenuList) => {
            return val.type !== "button"
        }
    },
    {
        label: "状态",
        type: "select",
        key: "status",
        option: [
            { label: "启用", value: true },
            { label: "禁用", value: false },
        ],
        show: (val: Menu.TreeMenuList) => {
            return val.type !== "button"
        }
    },
    {
        label: "组件路径",
        type: "input",
        key: "component",
        show: (val: Menu.TreeMenuList) => {
            return val.type === "menu"
        }
    },
    {
        label: "路由",
        type: "input",
        key: "path",
        show: (val: Menu.TreeMenuList) => {
            return val.type === "menu"
        }
    },
    {
        label: "是否外链",
        type: "radio",
        key: "link",
        show: (val: Menu.TreeMenuList) => {
            return val.type === "menu"
        },
        option: [
            {
                label: "是",
                value: true
            },
            {
                label: "否",
                value: false
            }
        ]
    },
    {
        label: "是否缓存",
        type: "radio",
        key: "cache",
        show: (val: Menu.TreeMenuList) => {
            return val.type === "menu"
        },
        option: [
            {
                label: "是",
                value: true
            },
            {
                label: "否",
                value: false
            }
        ]
    },
    {
        label: "权限字符",
        type: "input",
        key: "permission",
        show: (val: Menu.TreeMenuList) => {
            return val.type === "button"
        }
    },
    {
        label: "排序",
        type: "inputNumber",
        key: "sort",
    }
])
// 目录规则
const directoryRules: FormRules = {
    parentid: [
        { required: true, message: '请选择父级菜单id', trigger: "change" },
    ],
    name: [
        { required: true, message: '请输入菜单名称', trigger: 'blur' },
        { min: 2, max: 10, message: '菜单名称请控制在2-10个字符', trigger: 'blur' },
    ],
    type: [
        { required: true, message: '请选择菜单类型', trigger: 'blur' },
    ],
    status: [
        { required: true, message: "请选择菜单状态", trigger: "blur" }
    ],
    component: [
        { required: true, message: "请输入菜单路径", trigger: "blur" }
    ],
    path: [
        { required: true, message: "请输入菜单路由", trigger: "blur" }
    ],
    permission: [
        { required: true, message: "请输入权限字符", trigger: "blur" }
    ]
}
// 表单提交事件
const submit = () => {

    if (dialog.title === "新增") {
        append(dialog.form)
    }
    if (dialog.title === "修改") {
        modify(dialog.form)
    }
    dialog.visible = false
}
// ===========增加、修改表单配置项 end==============

// ===========表格操作 start=====================
interface TableProps {
    data: Menu.TreeMenuList[],
    rows: Menu.TreeMenuList[] | undefined,
}
// 表格项配置
const tableColumn: Table.Column[] = [
    {
        prop: "name",
        label: "菜单名称",
        minWidth: '150px'
    },
    {
        prop: "type",
        label: "菜单类型",
        minWidth: '100px',
        filter: (value) => {
            return value === "directory" ? "目录" : value === "menu" ? "菜单" : "按钮"
        }
    },
    {
        prop: "status",
        label: "菜单状态",
        minWidth: '100px',
        slot: true,
    },
    {
        prop: "icon",
        label: "菜单图标",
        minWidth: '100px',
        slot: true
    },
    {
        prop: "component",
        label: "组件路径",
        minWidth: '150px',
    },
    {
        prop: "path",
        label: "路由",
        minWidth: '150px',
    },
    {
        prop: "link",
        label: "是否外链",
        slot: true,
        minWidth: '100px',
    },
    {
        prop: "cache",
        label: "是否缓存",
        slot: true,
        minWidth: '100px',
    }
]
// 表格
const table = reactive<TableProps>({
    data: [],
    rows: undefined
})
const add = (_id?: string) => {
    dialog.form = {
        parentid: "",
        name: "",
        status: true,
        type: "directory"
    }
    dialog.visible = true
    dialog.title = "新增",
        _id ? dialog.form.parentid = _id : dialog.form.parentid = ""
}
const edit = (row: Menu.TreeMenuList) => {
    dialog.visible = true
    dialog.title = "修改"
    if (row.children) {
        delete row.children
        dialog.form = row
    } else {
        dialog.form = row
    }
}
const isdelete = (row: Menu.Directory | Menu.Menu) => {
    ElMessageBox.confirm(
        `是否删除 ${row.name} 及其子项？`,
        '警告',
        {
            confirmButtonText: '删除',
            cancelButtonText: '取消',
            type: 'warning',
            draggable: true,
        }
    ).then(() => {
        remove(row._id!)
    })

}
const selectionRows = (rowlist: Menu.TreeMenuList[]) => {
    table.rows = rowlist
}
// ===========表格操作 end=============

// ===========接口方法 start===========
// 查找
const find = async (query?: Menu.MenuSearchQuery) => {
    loading.value = true
    let res = await getMenuList(query)
    const { data, msg, code } = res.data
    if (!handleResponse(code, msg)) return loading.value = false
    table.data = data
    // 获取异步数据
    directoryFileds.value[0].option = [{ name: "主类目", _id: "0", children: [...data] }]
    loading.value = false
}
find()
// 新增
const append = async (query: Menu.Directory | Menu.Menu) => {
    loading.value = true
    let res = await appendMenu(query)
    const { msg, code, data } = res.data
    if (!handleResponse(code, msg)) return loading.value = false;
    ElMessage.success("新增成功")
    find()
}
// 修改
const modify = async (query: Menu.Directory | Menu.Menu) => {
    loading.value = true
    let res = await updateMenu(query)
    const { msg, code } = res.data
    if (!handleResponse(code, msg)) return loading.value = false;
    ElMessage.success("修改成功")
    find()
}
// 删除
const remove = async (id: string) => {
    let res = await removeMenu(id)
    const { msg, code } = res.data
    if (!handleResponse(code, msg)) return loading.value = false;
    ElMessage.success("删除成功")
    find()
}
// ===========接口方法 end= ============

nextTick(() => {
    loading.value = false
})

</script>
<style lang="less" scoped>
.icon {
    font-size: 26px;
    margin: 0px;
}
</style>